package com.atjg.autocat.viewModel


import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.util.Base64
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.atjg.autocat.UrlApi
import com.atjg.autocat.bean.BannerBean
import com.atjg.autocat.bean.DeliverInfo
import com.atjg.autocat.bean.DeviceInfo
import com.atjg.autocat.bean.GoodBean
import com.atjg.autocat.bean.OrderBean
import com.atjg.autocat.bean.PortBean
import com.atjg.autocat.bean.UpImgBean
import com.atjg.autocat.bean.UserBean
import com.atjg.autocat.utils.DeviceUtils
import com.atjg.autocat.utils.LogUtils
import com.atjg.autocat.utils.startTime
import com.blankj.utilcode.util.GsonUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.load.model.LazyHeaders
import com.google.gson.GsonBuilder
import com.zhy.baselibrary.base.BaseData
import com.zhy.baselibrary.base.BaseViewModel
import com.zhy.baselibrary.expand.ToastMgr
import com.zhy.baselibrary.utils.Klog
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date


class MainViewModel : BaseViewModel() {
    val login = MutableLiveData<String>().apply {}
    fun login(devId: String) {
        var mapNew = HashMap<String, Any?>()
        mapNew["id"] = devId
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).login(body) },
            {
                if (it.code == "200") {
                    login.postValue(it.data)
                    ToastMgr.show("添加设备成功")
                } else {
                    ToastMgr.show(it.message ?: "添加设备失败")
                    login(devId)
                }
            },
            {},
            true
        )
    }

    val queryBanner = MutableLiveData<List<BannerBean>>().apply {}
    fun queryBanner() {
        launch(
            { getApi(UrlApi::class.java).queryBanner() },
            {
                if (it.code == "200") {
                    queryBanner.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    //上传影像
    var uploadImg = MutableLiveData<Boolean>().apply { }
    fun uploadImg(orderNo: String, file: File) {
        val requestBody =
            RequestBody.create("multipart/form-data".toMediaType(), file)
        val body = MultipartBody.Part.createFormData("image", file.name, requestBody)
        val openIdBody = RequestBody.create("text/plain".toMediaTypeOrNull(), orderNo)
        launch(
            { getApi(UrlApi::class.java).uploadImg(body, openIdBody) },
            {
                Klog.d("-----上传图片----${it}-----------")
                if (it.code == "200") {
                    uploadImg.postValue(it.success)
                } else {
                    uploadImg.postValue(false)
                }
            },
            {
                uploadImg.postValue(false)
            }, false
        )
    }

    val queryCombo = MutableLiveData<List<GoodBean>>().apply {}
    fun queryCombo(devId: String) {
        launch(
            { getApi(UrlApi::class.java).queryCombo(devId) },
            {
                if (it.code == "200") {
                    queryCombo.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val queryXueHao = MutableLiveData<String>().apply {}
    fun queryXueHao(phoneNum: String) {
        launch(
            { getApi(UrlApi::class.java).queryXueHao(phoneNum) },
            {
                if (it.success && it.data != null) {
                    queryXueHao.postValue(phoneNum)
                } else {
                    queryXueHao.postValue("")
                }
            },
            {},
            true
        )
    }




    val queryPhone = MutableLiveData<UserBean>().apply {}
    fun queryPhone(openId: String) {
        launch(
            { getApi(UrlApi::class.java).queryPhone(openId) },
            {
                if (it.code == "200") {
                    queryPhone.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }


    val goodsList = MutableLiveData<List<GoodBean>>().apply {}
    fun goodsList(deviceId:String) {
        launch(
            { getApi(UrlApi::class.java).queryGoods(deviceId) },
            {
                if (it.code == "200") {
                    if (!it.data.isNullOrEmpty()){
                        goodsList.postValue(it.data)
                    }
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val queryNativePay = MutableLiveData<OrderBean>().apply {}
    fun queryNativePay(id: String) {
        launch(
            { getApi(UrlApi::class.java).queryNativePay(id) },
            {
                if (it.code == "200") {
                    queryNativePay.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val queryOrderStatus = MutableLiveData<OrderBean>().apply {}
    fun queryOrderStatus(orderNo: String) {
        launch(
            { getApi(UrlApi::class.java).queryOrderStatus(orderNo) },
            {
                if (it.code == "200") {
                    queryOrderStatus.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            false
        )
    }

    //上传影像
    var upImg = MutableLiveData<UpImgBean>().apply { }
    fun upImg(file: File) {
        val requestBody =
            RequestBody.create("multipart/form-data".toMediaType(), file)
        val body = MultipartBody.Part.createFormData("file", file.name, requestBody)
        launch(
            { getApi(UrlApi::class.java).upImg(body) },
            {
                if (it.code == "200") {
                    upImg.postValue(it.data)
                } else {
                    upImg.postValue(it.data)
                    ToastMgr.show(it.message ?: "上传失败")
                }
            },
            {
                upImg.postValue(null)
                ToastMgr.show(it ?: "上传失败")
            }, true
        )
    }

    fun upImg(key:String,file: File) {
        val requestBody =
            RequestBody.create("multipart/form-data".toMediaType(), file)
        val body = MultipartBody.Part.createFormData("file", file.name, requestBody)
        launch(
            { getApi(key,UrlApi::class.java).upImg(body) },
            {
                if (it.code == "200") {
                    upImg.postValue(it.data)
                } else {
                    upImg.postValue(it.data)
                    ToastMgr.show(it.message ?: "上传失败")
                }
            },
            {
                upImg.postValue(null)
                ToastMgr.show(it ?: "上传失败")
            }, true
        )
    }
    fun upNewImg(key:String,file: File) {
        val requestBody =
            RequestBody.create("multipart/form-data".toMediaType(), file)
        val body = MultipartBody.Part.createFormData("file", file.name, requestBody)
        launch(
            { getApi(key,UrlApi::class.java).upNewImg(body) },
            {
                if (it.code == "200") {
                    upImg.postValue(it.data)
                } else {
                    upImg.postValue(it.data)
                    ToastMgr.show(it.message ?: "上传失败")
                }
            },
            {
                upImg.postValue(null)
                ToastMgr.show(it ?: "上传失败")
            }, true
        )
    }




    //上传影像
    var verifyFaceFile = MutableLiveData<String>().apply { }
    fun verifyFaceFile(platForm: String, file: File) {
        val requestBody =
            RequestBody.create("multipart/form-data".toMediaType(), file)
        val body = MultipartBody.Part.createFormData("file", file.name, requestBody)
        launch(
            { getApi("face", UrlApi::class.java).verifyFaceFile(body, platForm) },
            {
                Klog.d("----------返回数据${GsonUtils.toJson(it)}-------------")
                if (it.code == "200") {
                    verifyFaceFile.postValue(it.data)
                } else {
                    verifyFaceFile.postValue(it.data)
                    ToastMgr.show(it.message ?: "上传失败")
                }
            },
            {
                Klog.d("----------返回数据${GsonUtils.toJson(it)}-------------")
                verifyFaceFile.postValue(null)
                ToastMgr.show(it ?: "上传失败")
            }, false
        )
    }


    val queryPortList = MutableLiveData<List<PortBean>>().apply {}
    fun queryPortList(isShowLoading: Boolean = true) {
        launch(
            { getApi(UrlApi::class.java).queryPortList() },
            {
                requestCount = 0
                if (it.code == "200") {
                    queryPortList.postValue(it.data)
                } else if (it.code == "401") {
                    login(DeviceUtils.getDeviceId())
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {
                if (requestCount < 3) {
                    ToastMgr.show("重新查询投口数据 $requestCount")
                    queryPortList(false)
                    requestCount++
                } else {
                    requestCount = 0
                    queryPortList.postValue(null)
                    ToastMgr.show(it ?: "")
                }
            },
            isShowLoading
        )
    }

    val queryCategoryDetail = MutableLiveData<PortBean>().apply {}
    fun queryCategoryDetail(operateType: String) {
        launch(
            { getApi(UrlApi::class.java).queryCategoryDetail() },
            {
                if (it.code == "200") {
                    it.data?.operateType = operateType
                    queryCategoryDetail.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            false
        )
    }



    private var requestCount = 0
    val submit = MutableLiveData<DeliverInfo?>().apply {}
    fun submit(
        openId: String,
        categoryId: String,
        fillPortId: String,
        itemWeight: Int,
        photoUrl: String
    ) {
        val mapNew = HashMap<String, Any?>()
        mapNew["openId"] = openId
        mapNew["categoryId"] = categoryId
        mapNew["fillPortId"] = fillPortId
        mapNew["itemWeight"] = itemWeight
        mapNew["photoUrl"] = photoUrl
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        Klog.d("------提交参数:$json-----")
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).submit(body) },
            {
                Klog.d("------提交返回数据:${GsonUtils.toJson(it)}-----")
                requestCount = 0
                if (it.code == "200") {
                    if (it.success) {
                        submit.postValue(it.data)
                    } else {
                        submit.postValue(null)
                        ToastMgr.show(it.msg ?: "获取数据失败")
                    }
                }else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {
                Klog.d("------提交报错:${it}-----")
                if (requestCount < 3) {
                    ToastMgr.show("重新提交数据 $requestCount")
                    submit(openId, categoryId, fillPortId, itemWeight, photoUrl)
                    requestCount++
                } else {
                    requestCount = 0
                    submit.postValue(null)
                    ToastMgr.show(it ?: "")
                }
            },
            true
        )
    }


    val xueHaoSubmit = MutableLiveData<DeliverInfo?>().apply {}
    fun xueHaoSubmit(
        openId: String,
        categoryId: String,
        fillPortId: String,
        itemWeight: Int,
        photoUrl: String
    ) {
        val mapNew = HashMap<String, Any?>()
        mapNew["openId"] = openId
        mapNew["categoryId"] = categoryId
        mapNew["fillPortId"] = fillPortId
        mapNew["itemWeight"] = itemWeight
        mapNew["photoUrl"] = photoUrl
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        Klog.d("------提交参数:$json-----")
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).xueHaoSubmit(body) },
            {
                Klog.d("------提交返回数据:${GsonUtils.toJson(it)}-----")
                requestCount = 0
                if (it.code == "200") {
                    if (it.success) {
                        xueHaoSubmit.postValue(it.data)
                    } else {
                        xueHaoSubmit.postValue(null)
                        ToastMgr.show(it.msg ?: "获取数据失败")
                    }
                }else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {
                Klog.d("------提交报错:${it}-----")
                if (requestCount < 3) {
//                    ToastMgr.show("重新提交数据 $requestCount")
                    submit(openId, categoryId, fillPortId, itemWeight, photoUrl)
                    requestCount++
                } else {
                    requestCount = 0
                    xueHaoSubmit.postValue(null)
                    ToastMgr.show(it ?: "")
                }
            },
            true
        )
    }

    val submitOrder = MutableLiveData<String>().apply {}
    fun submitOrder(openId: String, goodsId: String, goodsSum: Int) {
        val mapNew = HashMap<String, Any?>()
        mapNew["openId"] = openId
        mapNew["goodsId"] = goodsId
        mapNew["goodsSum"] = goodsSum
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        Klog.d("------提交参数:$json-----")
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).submitOrder(body) },
            {
                if (it.code == "200") {
                    if (it.success) {
                        submitOrder.postValue(it.data ?: "")
                    } else {
                        ToastMgr.show(it.msg ?: "提交失败")
                    }
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val submitOrderError = MutableLiveData<Any>().apply {}
    fun submitOrderError(openId: String, orderId: String, realSum: String) {
        var mapNew = HashMap<String, Any?>()
        mapNew["openId"] = openId
        mapNew["id"] = orderId
        mapNew["realSum"] = realSum
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).submitOrderError(body) },
            {
                if (it.code == "200") {
                    submitOrderError.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }


    private val fillPort = MutableLiveData<Any>().apply {}
    fun fillPort(id: String, state: Int) {
        val mapNew = HashMap<String, Any?>()
        mapNew["id"] = id
        mapNew["state"] = state.toString()
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).fillPort(body) },
            {
                if (it.code == "200") {
                    fillPort.postValue(it.data)
                }
            },
            {},
            false
        )
    }

    private val updateFullState = MutableLiveData<Any>().apply {}
    fun updateFullState(state: String) {
        launch(
            { getApi(UrlApi::class.java).updateFullState(state) },
            {
                if (it.code == "200") {
                    updateFullState.postValue(it.data)
                }
            },
            {},
            false
        )
    }


    private val updateFull = MutableLiveData<Any>().apply {}
    fun updateFull(id: String, state: String) {
        launch(
            { getApi(UrlApi::class.java).updateFull(id, state) },
            {
                if (it.code == "200") {
                    updateFull.postValue(it.data)
                }
            },
            {},
            false
        )
    }


    private val updateSmokeState = MutableLiveData<Any>().apply {}
    fun updateSmokeState(state: String) {
        launch(
            { getApi(UrlApi::class.java).updateSmokeState(state) },
            {
                if (it.code == "200") {
                    updateSmokeState.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            false
        )
    }


    fun updateQymState(state: String) {
        launch(
            { getApi(UrlApi::class.java).updateQymState(state) },
            {},
            {},
            false
        )
    }

    fun updateTdmState(state: String) {
        launch(
            { getApi(UrlApi::class.java).updateTdmState(state) },
            {},
            {},
            false
        )
    }
    fun updateState(adrHex:String,fullState: String,qymState:String,tdmState:String,smokeState:String) {
        val mapNew = HashMap<String, Any?>()
        mapNew["fullState"] = fullState
        mapNew["qymState"] = qymState
        mapNew["tdmState"] = tdmState
        mapNew["smokeState"] = smokeState
        mapNew["adrHex"] = adrHex
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).updateState(body) },
            {},
            {},
            false
        )
    }

    val queryVersion = MutableLiveData<BaseData<Any>>().apply {}
    fun queryVersion() {
        launch(
            { getApi(UrlApi::class.java).queryVersion() },
            {
                queryVersion.postValue(it)
            },
            {},
            true
        )
    }

    val queryAd = MutableLiveData<List<DeviceInfo>>().apply {}
    fun queryAd() {
        launch(
            { getApi(UrlApi::class.java).queryAd() },
            {
                queryAd.postValue(it.data)
            },
            {}, false

        )
    }

    val queryDeviceInfo = MutableLiveData<DeviceInfo>().apply {}
    fun queryDeviceInfo() {
        launch(
            { getApi(UrlApi::class.java).queryDeviceInfo() },
            {
                if (it.code == "200") {
                    queryDeviceInfo.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {}
        )
    }

    val bindUserICCard = MutableLiveData<String>().apply {}
    fun bindUserICCard(openId: String, icCard: String) {
        val mapNew = HashMap<String, Any?>()
        mapNew["id"] = openId
        mapNew["icCard"] = icCard
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).bindUserICCard(body) },
            {
                if (it.code == "200") {
                    bindUserICCard.postValue(it.data ?: "")
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val bindUserFinger = MutableLiveData<String>().apply {}
    fun bindUserFinger(openId: String, fingerPrint: String) {
        val mapNew = HashMap<String, Any?>()
        mapNew["openId"] = openId
        mapNew["fingerPrint"] = fingerPrint
        val gson = GsonBuilder().serializeSpecialFloatingPointValues().create()
        val json = gson.toJson(mapNew)
        val body = RequestBody.create("application/json; charset=utf-8".toMediaType(), json)
        launch(
            { getApi(UrlApi::class.java).bindUserFinger(body) },
            {
                if (it.code == "200") {
                    bindUserFinger.postValue(it.data ?: "")
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val queryFingerList = MutableLiveData<List<DeviceInfo>>().apply {}
    fun queryFingerList() {
        launch(
            { getApi(UrlApi::class.java).queryFingerList() },
            {
                if (it.code == "200") {
                    queryFingerList.postValue(it.data)
                } else {
                    ToastMgr.show(it.message ?: "获取数据失败")
                }
            },
            {},
            true
        )
    }

    val queryBitmap = MutableLiveData<Bitmap?>().apply {}
    @SuppressLint("SimpleDateFormat")
    fun queryBitmap(mContext: Context, url: String) {
        launchBitmap(
            {
                Glide.with(mContext).asBitmap().load(url).skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE).submit().get()
            },
            {
                queryBitmap.postValue(it)
            },
            {
                queryBitmap.postValue(null)
            }
        )
    }

    val queryBitmap2 = MutableLiveData<Bitmap?>().apply {}
    @SuppressLint("SimpleDateFormat")
    @OptIn(DelicateCoroutinesApi::class)
    fun queryBitmap2(mContext: Context, url: String) {
        launchBitmap(
            {
                val token = "Basic ${Base64.encodeToString(("admin:jxn124578").toByteArray(), 0)}"
                val glideUrl = GlideUrl(
                    url, LazyHeaders.Builder()
                        .addHeader("Authorization", token)
                        .build()
                )
                Glide.with(mContext).asBitmap().load(glideUrl).skipMemoryCache(true)
                    .diskCacheStrategy(DiskCacheStrategy.NONE).submit().get()
            },
            {
                queryBitmap2.postValue(it)
            },
            {
                GlobalScope.launch(Dispatchers.IO) {
                    LogUtils.initLog(mContext).input2File(
                        "${
                            SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(
                                Date()
                            )
                        }网络摄像头拍照失败$it\n"
                    )
                }
                queryBitmap2.postValue(null)
            }
        )
    }


    fun testTime(
        totalTime: Long?, onNext: (Long) -> Unit,
        onFinish: (() -> Unit)? = null,
        duration: Long = 1000L,
        interval: Long = 0L
    ): Job {
        return viewModelScope.startTime(
            totalTime, onNext, onFinish, duration = duration, interval = interval
        )
    }
}

